package com.quark.framework.ormapping;

import com.quark.data.type.QuarkVariable;
import com.quark.framework.utility.QuarkLog;
import com.quark.framework.utility.QuarkUtilStringConverter;
import com.quark.framework.utility.QuarkUtilStringConverter.QUARK_STRCONVERT_TYPE;

public class QuarkOrmProperty <T> {

	private Object content = null;
	private Object referObj = null;
	private Class<?> innerClass = null;
	private boolean isModified = false;
	QuarkOrmHost propHost = null;
	private Class<? extends QuarkOrmEntity> referClass = null;
	private String referKeyName = null;
	private boolean isUpdateKey = false;
	
	public QuarkOrmProperty(QuarkOrmHost host, Class<?> inClass)
	{
		innerClass = inClass;
		propHost = host;
		propHost.addItemMapping(this);
	}

	public QuarkOrmProperty(QuarkOrmHost host, Class<?> inClass, boolean isUpdateKey)
	{
		innerClass = inClass;
		propHost = host;
		propHost.addItemMapping(this);
		this.isUpdateKey = isUpdateKey;
		if(isUpdateKey)
		{
			propHost.setUpdateKey(this);
		}
	}
	
	public QuarkOrmProperty(QuarkOrmHost host, Class<?> inClass, Class<? extends QuarkOrmEntity> refClass)
	{
		innerClass = inClass;
		referClass = refClass;
		propHost = host;
		propHost.addItemMapping(this);
	}
	
	public boolean isUpdateKey()
	{
		return isUpdateKey;
	}
	
	public Class<?> getType()
	{		
		return innerClass;
	}
	
	public String toString()
	{
		if(content == null)
		{
			return "";
		}
		else
		{
			return content.toString();
		}
	}
	public String toSqlString()
	{
		return QuarkUtilStringConverter.convertString(getValue(), QUARK_STRCONVERT_TYPE.CONVERT_SQL);
	}
	@SuppressWarnings("unchecked")
	public T getValue()
	{
		return (T)content;
	}
	
	@SuppressWarnings("unchecked")
	public boolean setValue(Object value)
	{
		if(value != null && value.getClass().equals(innerClass))
		{
			isModified = true;
			propHost.setModified(true);
			content = (T)value;
			return true;
		}
		else
		{	
			QuarkLog.logError("QuarkOrmProperty:Set Value Failed," + innerClass.getName() + " Required, not " + value.getClass().getName());
			return false;
		}
	}
	
	public boolean setValue(QuarkVariable variable)
	{
		try
		{
			variable.setDefaultType(innerClass);
			if(!setValue(variable.toDefault()))
			{
				QuarkLog.logError(getClass().getName(), "can't set value from quarkvariable: " + variable.getRawObject().toString());
				return false;
			}
			return true;
		}
		catch(Exception e)
		{
			QuarkLog.logMessage(e.getMessage());
			return false;
		}
	}
	
	@SuppressWarnings("unchecked")
	public void setReferClass(String className)
	{
		try
		{
			this.referClass = (Class<? extends QuarkOrmEntity>)Class.forName(className);
		}catch(Exception e)
		{
			QuarkLog.log(e);
		}		
	}
	
	public boolean hasReferClass()
	{
		return referClass != null;
	}
	
	public Class<? extends QuarkOrmEntity> getReferClass()
	{
		return referClass;
	}
	
	public void setReferKey(String keyName)
	{
		this.referKeyName = keyName;
	}
	
	public boolean isForeighKey()
	{
		return referClass != null && referKeyName != null;
	}
	
	public void setReferObj(Object obj)
	{
		referObj = obj;
	}
	
	public Object getReferObj()
	{
		return referObj;
	}
	
	public String getName()
	{
		return propHost.getPropName(this);
	}
	
	public boolean isEmpty()
	{
		return content == null;
	}
	
	public boolean isModified()
	{
		return isModified;
	}
	
	public void setModified()
	{
		isModified = true;
	}
	
	public void clearModifyMark()
	{
		isModified = false;
	}
	
	public boolean equals(Object e)
	{
		return content.equals(e);
	}
	
	public boolean equals(QuarkOrmProperty<?> e)
	{
		return equals(e.getValue());
	}
}
